﻿using System;
using System.Web.Mvc;
using GabageFactory.Models;
using GabageFactory.Utiliy.Crypt;
using System.Text.RegularExpressions;
using System.Net.Mail;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;

namespace GabageFactory.Controllers
{
    [Authorize]
    public class PositionController : BaseController
    {
        private PositionReposity positionReposity;

        private FactoryReposity factoryReposity;

        private StackReposity stackReposity;

        private TailingpondReposity tailingpondReposity;

        private UserReposity userReposity;

        public PositionController()
        {
            positionReposity = new PositionReposity();
            factoryReposity = new FactoryReposity();
            userReposity = new UserReposity();
            stackReposity = new StackReposity();
            tailingpondReposity = new TailingpondReposity();
        }

        public ActionResult Search(string stackId)
        {
            List<RoleEnum> roles = new List<RoleEnum>();
            roles.Add(RoleEnum.Analyzer);
            roles.Add(RoleEnum.Auditor);
            roles.Add(RoleEnum.Expert);
            roles.Add(RoleEnum.Manager);
            roles.Add(RoleEnum.Recorder);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }

            long factoryId = 0;
            User user = GetCurrentUser();
            if (user.RoleId != (int)RoleEnum.Expert && user.RoleId != (int)RoleEnum.Analyzer)
            {
                factoryId = user.FactoryId;
            }

            int sid = 0;
            int type = 0;
            ParseSid(stackId, ref sid, ref type);
            ShowStackAndTailingoind(factoryId, 0, sid);

            IEnumerable<Position> positions = positionReposity.ListPositions(sid, type+1);

            ViewData["positions"] = positions;
            ViewData["user"] = user;

            return View();
        }

        public ActionResult List(long stackId, int type)
        {
            List<RoleEnum> roles = new List<RoleEnum>();
            roles.Add(RoleEnum.Administrator);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }
            long factoryId = 0;
            if (type == 1)
            {
                Stack s = stackReposity.GetStackById(stackId);
                factoryId = s == null ? 0 : s.FactoryId;
            }
            else
            {
                Tailingpond t = tailingpondReposity.GetTailingpondById(stackId);
                factoryId = t == null ? 0 : t.FactoryId;
            }
            IEnumerable<Position> positions = positionReposity.ListPositions(stackId, type);

            ViewData["positions"] = positions;
            ViewData["stackId"] = stackId;
            ViewData["id"] = stackId;
            ViewData["factoryId"] = factoryId;
            ViewData["type"] = type;

            return View();
        }

        public ActionResult AddPosition(long factoryId, long stackId, int type)
        {
            List<RoleEnum> roles = new List<RoleEnum>();
            roles.Add(RoleEnum.Administrator);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }

            if (type == 1)
            {
                Stack stack = stackReposity.GetStackById(stackId);
                ViewData["stackName"] = (stack == null ? "" : stack.Name);
            }
            else
            {
                Tailingpond tailingpond = tailingpondReposity.GetTailingpondById(stackId);
                ViewData["stackName"] = (tailingpond == null ? "" : tailingpond.Name);
            }

            Position p = new Position();
            p.FactoryId = factoryId;
            p.StackId = stackId;
            p.Type = type;

            return View(p);
        }

        [HttpPost]
        public ActionResult AddPosition(Position p)
        {
            List<RoleEnum> roles = new List<RoleEnum>();
            roles.Add(RoleEnum.Administrator);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }

            positionReposity.CreatePosition(p);

            return RedirectToAction("List", new { stackId = p.StackId, type = p.Type });
        }

        public ActionResult EditPosition(long positionId)
        {
            List<RoleEnum> roles = new List<RoleEnum>();
            roles.Add(RoleEnum.Administrator);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }
            Position p = positionReposity.GetPositionById(positionId);

            if (p.Type == 1)
            {
                Stack stack = stackReposity.GetStackById(p.StackId);
                ViewData["stackName"] = (stack == null ? "" : stack.Name);
            }
            else
            {
                Tailingpond tailingpond = tailingpondReposity.GetTailingpondById(p.StackId);
                ViewData["stackName"] = (tailingpond == null ? "" : tailingpond.Name);
            }

            return View("AddPosition", p);
        }

        [HttpPost]
        public ActionResult EditPosition(Position p)
        {
            List<RoleEnum> roles = new List<RoleEnum>();
            roles.Add(RoleEnum.Administrator);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }
            Position oldPosition = positionReposity.GetPositionById(p.Id);
            oldPosition.Name = p.Name;
            oldPosition.Description = p.Description;
            oldPosition.Status = p.Status;
            positionReposity.UpdatePosition(oldPosition);

            return RedirectToAction("List", new { stackId = p.StackId, type = p.Type });
        }

        public ActionResult AddPositionPicture(long positionId)
        {
            List<RoleEnum> roles = new List<RoleEnum>();
            roles.Add(RoleEnum.Recorder);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }
            User user = GetCurrentUser();
            ViewData["user"] = user;


            Position p = positionReposity.GetPositionById(positionId);
            if (p.Type == 1)
            {
                Stack s = stackReposity.GetStackById(p.StackId);
                ViewData["stackName"] = s.Name;
            }
            else
            {
                Tailingpond t = tailingpondReposity.GetTailingpondById(p.StackId);
                ViewData["stackName"] = t.Name;
            }
            DateTime date = DateTime.Now.Date;
            PositionPicture pp = positionReposity.GetPositionPictureByPositionIdAndDate(p.Id, date);
            if (pp == null)
            {
                pp = new PositionPicture();
                pp.PositionId = positionId;
                pp.Date = date;
            }

            ViewData["position"] = p;

            return View(pp);
        }

        [HttpPost]
        public ActionResult AddPositionPicture(PositionPicture pp, FormCollection form)
        {
            List<RoleEnum> roles = new List<RoleEnum>();
            roles.Add(RoleEnum.Recorder);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }

            Position p = positionReposity.GetPositionById(pp.PositionId);

            if (p.FirstUploadDate == null)
            {
                p.FirstUploadDate = pp.Date;
            }
            p.LastUploadDate = pp.Date;
            StoreImages(form, p, pp);
            PositionPicture oldPP = positionReposity.GetPositionPictureByPositionIdAndDate(pp.PositionId, pp.Date);
            if (oldPP == null)
            {
                positionReposity.CreatePositionPicture(pp);
            }
            else
            {
                oldPP.PicNum = pp.PicNum;
                oldPP.Pic1 = pp.Pic1;
                oldPP.PicDesc1 = pp.PicDesc1;
                oldPP.Pic2 = pp.Pic2;
                oldPP.PicDesc2 = pp.PicDesc2;
                oldPP.Pic3 = pp.Pic3;
                oldPP.PicDesc3 = pp.PicDesc3;
                oldPP.Pic4 = pp.Pic4;
                oldPP.PicDesc4 = pp.PicDesc4;
                positionReposity.UpdatePositionPicture(oldPP);
            }
            positionReposity.UpdatePosition(p);

            return RedirectToAction("Search", new { stackId = (p.Type - 1) + "-" + p.StackId });
        }

        public ActionResult EditPositionPicture(long id)
        {
            List<RoleEnum> roles = new List<RoleEnum>();
            roles.Add(RoleEnum.Recorder);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }

            PositionPicture pp = positionReposity.GetPositionPictureById(id);
            Position p = positionReposity.GetPositionById(pp.PositionId);
            ViewData["position"] = p;

            return View("AddPositionPicture", pp);
        }

        [HttpPost]
        public ActionResult EditPositionPicture(PositionPicture pp, FormCollection form)
        {
            List<RoleEnum> roles = new List<RoleEnum>();
            roles.Add(RoleEnum.Recorder);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }
            pp.Date = DateTime.Now.Date;

            Position p = positionReposity.GetPositionById(pp.PositionId);
            p.LastUploadDate = pp.Date;
            StoreImages(form, p, pp);
            positionReposity.UpdatePositionPicture(pp);
            positionReposity.UpdatePosition(p);

            return RedirectToAction("List", new { stackId = p.StackId, type = p.Type });
        }

        public ActionResult Detail(long positionId, long? pictureId)
        {
            List<RoleEnum> roles = new List<RoleEnum>();
            roles.Add(RoleEnum.Recorder);
            roles.Add(RoleEnum.Auditor);
            roles.Add(RoleEnum.Manager);
            roles.Add(RoleEnum.Analyzer);
            roles.Add(RoleEnum.Expert);
            roles.Add(RoleEnum.Administrator);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }

            Position p = positionReposity.GetPositionById(positionId);
            if (p.Type == 1)
            {
                Stack s = stackReposity.GetStackById(p.StackId);
                ViewData["stackName"] = s.Name;
            }
            else
            {
                Tailingpond t = tailingpondReposity.GetTailingpondById(p.StackId);
                ViewData["stackName"] = t.Name;
            }
            IEnumerable<PositionPicture> pictures = positionReposity.ListPositionPictures(positionId);
            PositionPicture firstRecord = pictures.First();
            PositionPicture lastRecord = pictures.Last();
            List<PositionPicture> pictureList = pictures.ToList();
            PositionPicture picture = null;
            long prePictureId = 0;
            long nextPictureId = 0;
            if (!pictureId.HasValue)
            {
                pictureId = pictureList.Last().Id;
            }
            int i = 0;
            for (i = 0; i < pictureList.Count; i++)
            {
                if (pictureList[i].Id == pictureId)
                {
                    picture = pictureList[i];
                    if (i > 0)
                    {
                        prePictureId = pictureList[i - 1].Id;
                    }
                    if (i < (pictureList.Count - 1))
                    {
                        nextPictureId = pictureList[i + 1].Id;
                    }
                    break;
                }
            }


            ViewData["position"] = p;
            ViewData["firstRecord"] = firstRecord;
            ViewData["lastRecord"] = lastRecord;
            ViewData["picture"] = picture;
            ViewData["prePictureId"] = prePictureId;
            ViewData["nextPictureId"] = nextPictureId;
            ViewData["totalCount"] = pictureList.Count;
            ViewData["index"] = (i + 1);

            return View();
        }

        private void StoreImages(FormCollection form, Position p, PositionPicture pp)
        {
            string picPath1 = form.Get("picPath1");
            string picDes1 = form.Get("picDes1");
            string picPath2 = form.Get("picPath2");
            string picDes2 = form.Get("picDes2");
            string picPath3 = form.Get("picPath3");
            string picDes3 = form.Get("picDes3");
            string picPath4 = form.Get("picPath4");
            string picDes4 = form.Get("picDes4");

            pp.PicNum = 0;
            string oldPicPath = null;
            if (!string.IsNullOrEmpty(picPath1))
            {
                oldPicPath = pp.Pic1;
                pp.Pic1 = picPath1;
                pp.PicDesc1 = picDes1;
                pp.PicNum = pp.PicNum + 1;
                pp.Pic1 = MoveImage(p, pp, pp.Pic1, 1, oldPicPath);
            }
            else
            {
                pp.Pic1 = null;
                pp.PicDesc1 = null;
            }

            if (!string.IsNullOrEmpty(picPath2))
            {
                oldPicPath = pp.Pic2;
                pp.Pic2 = picPath2;
                pp.PicDesc2 = picDes2;
                pp.PicNum = pp.PicNum + 1;
                pp.Pic2 = MoveImage(p, pp, pp.Pic2, 2, oldPicPath);
            }
            else
            {
                pp.Pic2 = null;
                pp.PicDesc2 = null;
            }

            if (!string.IsNullOrEmpty(picPath3))
            {
                oldPicPath = pp.Pic3;
                pp.Pic3 = picPath3;
                pp.PicDesc3 = picDes3;
                pp.PicNum = pp.PicNum + 1;
                pp.Pic3 = MoveImage(p, pp, pp.Pic3, 3, oldPicPath);
            }
            else
            {
                pp.Pic3 = null;
                pp.PicDesc3 = null;
            }

            if (!string.IsNullOrEmpty(picPath4))
            {
                oldPicPath = pp.Pic4;
                pp.Pic4 = picPath4;
                pp.PicDesc4 = picDes4;
                pp.PicNum = pp.PicNum + 1;
                pp.Pic4 = MoveImage(p, pp, pp.Pic4, 4, oldPicPath);
            }
            else
            {
                pp.Pic4 = null;
                pp.PicDesc4 = null;
            }
        }

        private string MoveImage(Position p, PositionPicture pp, string path, int index, string oldPicPath)
        {
            string fileName = !path.StartsWith("~") ? ("~" + path) : path;
            long tick = DateTime.Now.Ticks; 
            Random ran = new Random((int)(tick & 0xffffffffL) | (int)(tick >> 32)); 
            if (fileName.StartsWith("~/Upload/Images/"))
            {
                string stackFolder = p.FactoryId.ToString("00") + p.StackId.ToString("00") + (p.Type == 1 ? "dc" : "wk");
                string dateFolder = p.Id.ToString("00") + "_" + pp.Date.ToString("yyyyMMdd");
                string filePath = "~/Upload/Positions/" + stackFolder + "/" + dateFolder + "/";
                string fullPath = Server.MapPath(filePath);
                fileName = filePath + index + "_" + ran.Next(1000) + ".jpg";
                path = Server.MapPath("~" + path);
                string fullFileName = Server.MapPath(fileName);
                if (!Directory.Exists(fullPath))
                {
                    Directory.CreateDirectory(fullPath);
                }
                System.IO.File.Copy(path, fullFileName, true);
                System.IO.File.Delete(path);
                if (!string.IsNullOrEmpty(oldPicPath) && System.IO.File.Exists(Server.MapPath(oldPicPath)))
                {
                    System.IO.File.Delete(Server.MapPath(oldPicPath));
                }
            }
            return fileName;
        }

        [HttpPost]
        public ActionResult FileUpload(HttpPostedFileWrapper file)
        {
            string error = "";
            string url = "";
            if (file != null)
            {
                /*
                if (!string.Equals("image/jpeg", file.ContentType, StringComparison.CurrentCultureIgnoreCase) && !string.Equals("image/pjpeg", file.ContentType, StringComparison.CurrentCultureIgnoreCase))
                {
                    error = "只能上传jpeg格式图片.";
                }
                else 
                */
                if (file.ContentLength > 200 * 1024)
                {
                    error = "文件太大，必须小于200KB.";
                }
                else
                {
                    url = UploadFile(file, FileType.Image);
                }
            }
            ViewData["error"] = error;
            ViewData["url"] = url;

            return View();
        }

        [HttpPost]
        public ActionResult DelFile(string file)
        {
            string error = DeleteFile(file);
            string url = "~/";
            

            ViewData["error"] = error;
            ViewData["url"] = url;

            return View("FileUpload");
        }

        private string DeleteFile(string file)
        {
            string error = "";
            try
            {
                if (file != null && (file.StartsWith("/Upload/") || file.StartsWith("~/Upload/")))
                {
                    if (!file.StartsWith("~"))
                    {
                        file = "~" + file;
                    }
                    string path = Server.MapPath(file);
                    if (System.IO.File.Exists(path))
                    {
                        System.IO.File.Delete(path);
                    }
                }
            }
            catch (Exception e)
            {
                error = e.Message;
            }

            return error;
        }
    }
}
